/** 泛型 */
// typescriptlang.org/docs/handbook/2/generics.html
/** --------- function --------- */
function fn<T>(arg: T): T {
    return arg;
}

// let output = fn<string>(1) // 类型错误，报错
let output = fn<string>("123")
output = fn("555");


function fn1<T>(arg: T): T[] {
    return [arg];
}


// let myFunc: <T>(arg: T): T = fn; // 自己是这样写的，会报错，记住相关写法
let myFunc: <T>(arg: T) => T = fn;
// 注意和上面的区别：上面是 => ;下面是 ：  ； 同时，下面看着像是对象！！！这个有点费解
let myFn1: { <T>(arg: T): T } = fn;
// 上面的写法拆解下
interface F {
    <T>(arg: T): T;
}
let myFn2: F = fn;

// 可以把泛型加到外面
interface F1<T> {
    (arg: T): T;
}
let myFn3: F1<string> = fn;

/** --------- class --------- */
class C<T> {
    name: T;
}
let c = new C<string>();
// c.name = 123; // 报错
c.name = "name";


/** --------- extends 约束 --------- */
interface L {
    length: number;
}

function f<T extends L>(args: T): T {
    console.info(args.length);
    return args;
}



/** keyof */
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
    return obj[key];
  }
   
  let x = { a: 1, b: 2, c: 3, d: 4 };
   
  getProperty(x, "a");
//   getProperty(x, "m");


/***        Using Class Types in Generics   有点繁琐，还从来没有使用过 */
// new () => T  表示传入的是一个class，new class后获得的typeof，或者说instanceof 是T
class A {
    aname: string;
}
function fff<T extends A>(args: new () => T): T {
    return new args(); // 这里new args以后就是T，同时T又是受限制于A的！！
}




